package com.impress.service;


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.R.string;
import android.content.Context;
import android.os.Environment;

import com.impress.Utility;
import com.impress.Utility.SDCardException;
import com.impress.model.Item;



public class HtmlHandler {

	private static Document document = null;
	private static Elements elements = null;
	
	private static final String TAG_IMG = "img";
	private static final String ATTR_SRC = "src";
	
	private Item mItem;
	private Context mContext;
	
	private String mPath;
	private String mPrefixName;
	private String mFileName;
	private int mImgCount = 0;
	private String mNewSrc;
	private boolean downloadSuccess = true;
	
	public HtmlHandler(Item item, Context context){
		mItem = item;
		mContext = context;
		mPrefixName = Utility.parseItemId(mItem.getAtomID());
		mPath = "/Android/data/" + mContext.getPackageName() + "/" + mPrefixName;
		mFileName = mPrefixName;
	}
	
	public boolean isDownloadSuccess() {
		return downloadSuccess;
	}

	public boolean start() throws Exception{
		boolean isSuccess = false;
		String html = handleImg(mItem.getContent(),false);
		html = generateHTML(html,mItem);
		isSuccess = saveHTML(html);
		return (downloadSuccess && isSuccess);
	}
	
	public boolean resume() throws Exception{
		boolean isSuccess = false;
		String html = handleImg(getHTML(),true);
		isSuccess = saveHTML(html);
		return (downloadSuccess && isSuccess);
	}
	
	public String handleImg(String html, boolean outHtml) throws Exception{		
		document = Jsoup.parseBodyFragment(html);
		elements = document.getElementsByTag(TAG_IMG);
		boolean FirstImgDownloaded = false;
		for (Element element : elements) {
			String imgSrc = element.attr(ATTR_SRC);
			mImgCount++;
			if (imgSrc.startsWith("file:")) {
				continue;
			}
			if (Utility.EmptyString(imgSrc)) {
				continue;
			}
			if(Utility.isAds(imgSrc)){
				element.attr(ATTR_SRC, "");
				continue;
			}
			if (downloadImg(imgSrc)) {
				element.attr(ATTR_SRC, mNewSrc);
				if(!FirstImgDownloaded && Utility.EmptyString(mItem.getPreviewImg())){
					mItem.setPreviewImg(mNewSrc);
					FirstImgDownloaded = true;
				}
			}else {
				downloadSuccess = false;
			}
		}
		return (outHtml?document.body().outerHtml():document.body().html());
	}
	
	private boolean downloadImg(String src) throws Exception{
		boolean isSuccess = false;
		if (Utility.EmptyString(src)) {
			return true;
		}
		try {
			byte[] bytes = GDataClient.doGet(src);
			File fileDir = getItemDir();
			File newFile = new File(fileDir, mFileName);
			if (!newFile.exists()) {
				newFile.createNewFile();
			}
			mNewSrc = "file://" + newFile.getAbsolutePath();
			FileOutputStream stream = new FileOutputStream(newFile);
			stream.write(bytes);
			stream.close();
			isSuccess = true;
			
		} catch (Exception e) {
			if (e instanceof SDCardException) {
				throw e;
			}
			
		}
		return isSuccess;
	}
	
	public static boolean isSDCardAvailable(){
		return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
	}
	
	public static String generateHTML(String html,Item item){		
		String prependString = "<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head>" +
				"<body>" +
				"<style type=\"text/css\">" +
				"body{margin-left:auto;margin-right:auto;width:90%}" +
				"p{text-align:left}"+
				"#header{padding-top:20px;margin-left:0px;text-align:left;}" +
				"#header h3{margin-bottom:0px;}" +
				"#header p{font-size:small;margin-top:5px;padding-left:5px;}" +
				"#footer{margin-bottom:30px; background:#000000;padding:20px;text-align:center}"+
				"a, a:visited{text-decoration:none;color:#006699;}"+
				".borderImage {-webkit-tap-highlight-color:rgba(0,0,0,0);} "+
				"</style>" +
				"<div id=\"header\"><h3>" + item.getTitle() + "</h3>" +
				"<p>" +Utility.convertLongToDate(Long.parseLong(item.getUpdateTimestamp()+"000"))+ 
				"<br />BY " + item.getAuthor() +": " + item.getFeedTitle() +"</p><hr /></div>";
		
		String appendString = "<div id=\"footer\"><hr/><a href=\"" + item.getAlternateUrl()+
				"\">Go to original web page</a></div></body>";
		
		return prependString + BanAds(html) + appendString;
	}
	
	private static String BanAds(String html){
		Document bodyDocument = Jsoup.parseBodyFragment(html);
		Elements checkNodes = bodyDocument.getElementsByTag(TAG_IMG);
		for (int i = 0; i < checkNodes.size(); i++) {
			String src = checkNodes.get(i).attr(ATTR_SRC);
			if(Utility.isAds(src)){
				checkNodes.get(i).remove();
			}
		}
		checkNodes = bodyDocument.getElementsByTag("iframe");
		for (int i = 0; i < checkNodes.size(); i++) {
			String src = checkNodes.get(i).attr(ATTR_SRC);
			if(Utility.isAds(src)){
				checkNodes.get(i).remove();
			}
		}
		return bodyDocument.body().html();
	}
	
	private String getHTML() throws Exception{
		File itemDir = getItemDir();
		File htmlFile = new File(itemDir, mPrefixName+".html");
		InputStream stream = new FileInputStream(htmlFile);
		return Utility.convertStreamToString(stream);
	}
	
	public File getItemDir() throws Exception{
		if (isSDCardAvailable()) {
			File sdCardDir = Environment.getExternalStorageDirectory();
			String path = sdCardDir.getPath() + mPath;
			mFileName = mPrefixName + "_" + mImgCount;
			File itemDir = new File(path);
			//the file dir dose not exist, make it.
			if (!itemDir.exists()) {
				itemDir.mkdirs();
			}
			return itemDir;
		}else {
			throw new SDCardException("SD card is not available");
		}
	}
	
	public static File getDataDir(Context context){
		File file = null;
		if (isSDCardAvailable()) {
			File sdCardDir = Environment.getExternalStorageDirectory();
			String path = sdCardDir.getPath() + "/Android/data/"+context.getPackageName();
			file = new File(path);
			if (!file.exists()) {
				file = null;
			}
		}
		return file;
	}
	
	private boolean saveHTML(String html) throws Exception{
		boolean isSuccess = false;
		try{
			File itemDir = getItemDir();
			File htmlFile = new File(itemDir, mPrefixName+".html");
			if (!htmlFile.exists()) {
				
				htmlFile.createNewFile();
				
			}
			BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(htmlFile));
			stream.write(html.getBytes("utf-8"));
			stream.flush();
			stream.close();
			isSuccess = true;
		
		}catch (Exception e) {
			if (e instanceof SDCardException) {
				throw e;
			}
		}
		return isSuccess;
	}
	
	public static String htmlToText(String html){
		Document documents = Jsoup.parseBodyFragment(html);
		return documents.body().text();
	}
	
}
